
package com.rt.schedulenew.service.impl;

import com.rt.schedulebase.entity.DictExamClass;
import com.rt.schedulebase.entity.ExamScheduleCharts;
import com.rt.schedulebase.mapper.ExamScheduleChartsMapper;
import com.rt.schedulenew.utils.util.DateUtil;
import org.slf4j.LoggerFactory;
import java.util.*;
import com.rt.schedulebase.dto.ScheduleChartsTrendDto;
import com.rt.schedulebase.dto.ScheduleChartsDataDto;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.CompletableFuture;
import java.text.DecimalFormat;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.text.SimpleDateFormat;
import com.rt.schedulenew.utils.base.CommonUtil;
import org.apache.commons.lang3.StringUtils;
import com.rt.schedulebase.dto.ScheduleChartsRequestDto;
import com.rt.schedulebase.dto.ScheduleChartsResponseDto;
import java.util.concurrent.Semaphore;
import com.rt.schedulebase.mapper.ResultSaveMapper;
import org.springframework.beans.factory.annotation.Autowired;
import com.rt.schedulebase.mapper.ScheduleChartsMapper;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;
import com.rt.schedulenew.api.IScheduleChartsService;
import org.springframework.util.CollectionUtils;

@Service
public class ScheduleChartsServicelmpl implements IScheduleChartsService {
    private static final Logger log = LoggerFactory.getLogger(ScheduleChartsServicelmpl.class);
    @Autowired
    private ScheduleChartsMapper scheduleChartsMapper;
    @Autowired
    private ExamScheduleChartsMapper examScheduleChartsMapper;
    @Autowired
    private ResultSaveMapper resultSaveMapper;
    private static final String ZERO = "0";
    private static final String WEEK = "week";
    private static final String COMPLETE = "全部";
    private static final String Whole_Hospital = "全院";
    private static final String Check_Wait_Time = "00:00:00";
    private static final Semaphore semaphore = new Semaphore(1);

    @Override
    public ScheduleChartsResponseDto getDictHospitalList() {
        ScheduleChartsResponseDto response = new ScheduleChartsResponseDto();
        response.setDictHospital(scheduleChartsMapper.getDictHospital());
        return response;
    }

    @Override
    public ScheduleChartsResponseDto getExamClassList(ScheduleChartsRequestDto request) {
        ScheduleChartsResponseDto response = new ScheduleChartsResponseDto();
        if (StringUtils.isNotBlank(request.getExamClass())) {
            request.setExamClassList(CommonUtil.split2List(request.getExamClass()));
        }
        List<DictExamClass> list = scheduleChartsMapper.getExamClass(request);
        List<String> examClass = new ArrayList<>();
        Iterator<DictExamClass> it = list.iterator();
        examClass.add("全院");
        while (it.hasNext()) {
            DictExamClass dec = it.next();
            if (StringUtils.isBlank(dec.getHospitalCode()) || !dec.getHospitalCode().contains(request.getHospitalCode())) {
                it.remove();
            } else {
                examClass.add(dec.getExamClassName());
            }
        }
        response.setExamClass(examClass);
        return response;
    }

    private void getTime(ScheduleChartsRequestDto dto) {
        if (StringUtils.isEmpty(dto.getStartTime())) {
            Date d = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String dateNowStr = sdf.format(d);
            dto.setStartTime(dateNowStr);
            dto.setEndTime(dateNowStr);
        }
    }

    @Override
    public ScheduleChartsResponseDto getChartsDataAnalysis(ScheduleChartsRequestDto request, ScheduleChartsResponseDto response, String dataSourceType) {
        String examClass = "全院".equals(request.getExamClassName()) ? "" : request.getExamClassName();
        if (StringUtils.isNotBlank(examClass)) {
            request.setExamClassList(CommonUtil.split2List(examClass));
        }
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String chartsDate = sdf.format(d);
        boolean isRealTime = false;
        if ((chartsDate.equals(request.getStartTime()) && chartsDate.equals(request.getEndTime())) || (StringUtils.isBlank(request.getStartTime()) && StringUtils.isBlank(request.getEndTime()))) {
            isRealTime = true;
            request.setStartTime(chartsDate);
            request.setEndTime(chartsDate);
        }
        if ("1".equals(dataSourceType) && isRealTime) {
            getScheduleChartsNum(request, response);
            return response;
        }
        getScheduleChartsNumForCharts(request, response);
        if ("2".equals(dataSourceType) && isRealTime) {
            ExamScheduleCharts chasrts = new ExamScheduleCharts();
            chasrts.setChartsDate(chartsDate);
            asynchronous(chasrts);
        }
        return response;
    }

    public void asynchronous(ExamScheduleCharts chasrts) {
        ExecutorService ex = Executors.newSingleThreadExecutor();
        ex.execute(new Runnable() {
            @Override
            public void run() {
                int availablePermits = semaphore.availablePermits();
                if (availablePermits > 0) {
                    try {
                        semaphore.acquire(1);
                        saveExamScheduleCharts(chasrts);
                    } catch (InterruptedException e) {
                        log.error(e.getMessage(), e);
                    } finally {
                        semaphore.release(1);
                    }
                }
                ex.shutdown();
            }

            private void saveExamScheduleCharts(ExamScheduleCharts chasrts) {
                examScheduleCharts(chasrts);
            }
        });
    }

    public void getScheduleChartsNumForCharts(ScheduleChartsRequestDto request, ScheduleChartsResponseDto response) {
        DecimalFormat df = new DecimalFormat("0.##");
        Map<String, String> map = new HashMap<>();
        for (int i = 1; i < 10; ++i) {
            String type = "8".equals(String.valueOf(i)) ? "A" : ("9".equals(String.valueOf(i)) ? "B" : String.valueOf(i));
            request.setType(type);
            map.put(type, examScheduleChartsMapper.getExamScheduleChartsNum(request));
        }
        String allocatedQuantity = map.get("1");
        String inspectionQuantity = map.get("2");
        String complianceQuantity = map.get("3");
        String timelyArrivalQuantity = map.get("4");
        String scheduleInspectionQuantity = map.get("5");
        String checkWaitTimeMinute = map.get("6");
        String reservationTimeHour = map.get("7");
        String openOrderNum = map.get("A");
        String reservationRateQuantity = map.get("B");
        long checkWaitCount = Long.parseLong(scheduleInspectionQuantity);
        if (0L != checkWaitCount) {
            long checkWaitSecond = Long.parseLong(checkWaitTimeMinute) * 60L;
            long avgCheckWaitSecond = checkWaitSecond / checkWaitCount * 1000L;
            String checkWaitTime = DateUtil.msecToTime(avgCheckWaitSecond);
            response.setCheckWaitTime(checkWaitTime);
        }
        String reservationRateVal = "";
        if (!ZERO.equals(openOrderNum) && !ZERO.equals(reservationRateQuantity)) {
            double reservationRate = Double.parseDouble(reservationRateQuantity) / Double.parseDouble(openOrderNum) * 100.0;
            reservationRateVal = handleParam(df.format(reservationRate), 0);
        }
        response.setReservationRate(reservationRateVal);
        String timelyArrivalRateVal = "";
        String complianceRateVal = "";
        String averageReservationTimeVal = "";
        if (!ZERO.equals(allocatedQuantity)) {
            if (!ZERO.equals(timelyArrivalQuantity)) {
                double timelyArrivalRate = Double.parseDouble(timelyArrivalQuantity) / Double.parseDouble(allocatedQuantity) * 100.0;
                timelyArrivalRateVal = handleParam(df.format(timelyArrivalRate), 0);
            }
            if (!ZERO.equals(complianceQuantity)) {
                double complianceRate = Double.parseDouble(complianceQuantity) / Double.parseDouble(allocatedQuantity) * 100.0;
                complianceRateVal = handleParam(df.format(complianceRate), 0);
            }
            if (!ZERO.equals(reservationTimeHour)) {
                double averageReservationTime = Double.parseDouble(reservationTimeHour) / Double.parseDouble(allocatedQuantity);
                averageReservationTimeVal = handleParam(df.format(averageReservationTime), 1);
            }
        }
        response.setTimelyArrivalRate(timelyArrivalRateVal);
        response.setComplianceRate(complianceRateVal);
        response.setAverageReservationTime(averageReservationTimeVal);
        response.setAllocatedQuantity(isNotNull(allocatedQuantity));
        response.setInspectionQuantity(isNotNull(inspectionQuantity));
    }

    @Override
    public ScheduleChartsResponseDto getChartsDataGraphAnalysis(ScheduleChartsRequestDto request, String dataSourceType) {
        ScheduleChartsResponseDto response = new ScheduleChartsResponseDto();
        boolean isRealTime = false;
        if (StringUtils.isBlank(request.getStartTime()) && StringUtils.isBlank(request.getEndTime())) {
            isRealTime = true;
            Date d = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String chartsDate = sdf.format(d);
            request.setStartTime(chartsDate);
            request.setEndTime(chartsDate);
        }
        String examClass = "全院".equals(request.getExamClassName()) ? "" : request.getExamClassName();
        if (StringUtils.isNotBlank(examClass)) {
            request.setExamClassList(CommonUtil.split2List(examClass));
        }
        if ("1".equals(dataSourceType) && isRealTime) {
            getScheduleChartsGraphical(response, request);
            return response;
        }
        getScheduleChartsGraphicalForCharts(response, request);
        return response;
    }

    private void getScheduleChartsNum(ScheduleChartsRequestDto scheduleChartsRequestDto, ScheduleChartsResponseDto scheduleChartsResponseDto) {
        CompletableFuture<List<Map<String, Object>>> reservationRateQuantityFuture = CompletableFuture.supplyAsync(() -> scheduleChartsMapper.getReservationRateQuantity(scheduleChartsRequestDto));
        CompletableFuture<List<Map<String, Object>>> complianceQuantityFuture = CompletableFuture.supplyAsync(() -> scheduleChartsMapper.getComplianceQuantityCount(scheduleChartsRequestDto));
        CompletableFuture<String> reservationTimeFuture = CompletableFuture.supplyAsync(() -> scheduleChartsMapper.getAverageReservationTime(scheduleChartsRequestDto));
        CompletableFuture.allOf(reservationRateQuantityFuture, complianceQuantityFuture, reservationTimeFuture);
        try {
            List<Map<String, Object>> openOrderNumList = scheduleChartsMapper.getOpenOrderNum(scheduleChartsRequestDto);
            String openOrderNum = "0";
            if (openOrderNumList != null && openOrderNumList.size() > 0) {
                openOrderNum = ((openOrderNumList.get(0).get("openOrderNum") == null) ? "0" : (openOrderNumList.get(0).get("openOrderNum") + ""));
            }
            List<Map<String, Object>> reservationRateQuantityList = reservationRateQuantityFuture.get();
            String reservationRateQuantity = "0";
            if (reservationRateQuantityList != null && reservationRateQuantityList.size() > 0) {
                reservationRateQuantity = ((reservationRateQuantityList.get(0).get("reservationRateQuantity") == null) ? "0" : (reservationRateQuantityList.get(0).get("reservationRateQuantity") + ""));
            }
            List<Map<String, Object>> allocatedQuantityList = scheduleChartsMapper.getAllocatedQuantity(scheduleChartsRequestDto);
            String allocatedQuantity = "0";
            if (allocatedQuantityList != null && allocatedQuantityList.size() > 0) {
                allocatedQuantity = ((allocatedQuantityList.get(0).get("allocatedQuantity") == null) ? "0" : (allocatedQuantityList.get(0).get("allocatedQuantity") + ""));
            }
            String inspectionQuantity = scheduleChartsMapper.getInspectionQuantity(scheduleChartsRequestDto);
            String timelyArrivalQuantity = scheduleChartsMapper.getTimelyArrivalQuantity(scheduleChartsRequestDto);
            List<Map<String, Object>> complianceQuantityList = complianceQuantityFuture.get();
            String complianceQuantity = "0";
            if (complianceQuantityList != null && complianceQuantityList.size() > 0) {
                complianceQuantity = complianceQuantityList.get(0).get("complianceQuantity") + "";
            }
            List<Map<String, Object>> checkWaitTimeList = scheduleChartsMapper.getCheckWaitTime(scheduleChartsRequestDto);
            String checkWaitTime = getCheckWaitTime(checkWaitTimeList);
            String reservationTime = reservationTimeFuture.get();
            getScheduleChartsNumber(scheduleChartsResponseDto, allocatedQuantity, inspectionQuantity, complianceQuantity, reservationTime, timelyArrivalQuantity, openOrderNum, reservationRateQuantity, checkWaitTime);
        } catch (InterruptedException | ExecutionException ex2) {
            log.error(ex2.getMessage(), ex2);
        }
    }

    private String getCheckWaitTime(List<Map<String, Object>> checkWaitTimeList) {
        String checkWaitTime = Check_Wait_Time;
        if (checkWaitTimeList != null && checkWaitTimeList.size() > 0) {
            long checkWaitCount = Long.parseLong(checkWaitTimeList.get(0).get("checkWaitCount") + "");
            if (0L != checkWaitCount) {
                DecimalFormat fnum = new DecimalFormat("0");
                long checkWaitSecond = Long.parseLong(fnum.format(checkWaitTimeList.get(0).get("checkWaitTime")));
                long avgCheckWaitSecond = checkWaitSecond / checkWaitCount * 1000L;
                checkWaitTime = DateUtil.msecToTime(avgCheckWaitSecond);
            }
        }
        return checkWaitTime;
    }

    private void getScheduleChartsNumber(ScheduleChartsResponseDto scheduleChartsResponseDto, String allocatedQuantity, String inspectionQuantity, String complianceQuantity, String reservationTime, String timelyArrivalQuantity, String openOrderNum, String reservationRateQuantity, String checkWaitTime) {
        try {
            DecimalFormat df = new DecimalFormat("0.##");
            scheduleChartsResponseDto.setAllocatedQuantity(isNotNull(allocatedQuantity));
            scheduleChartsResponseDto.setInspectionQuantity(isNotNull(inspectionQuantity));
            scheduleChartsResponseDto.setCheckWaitTime(checkWaitTime);
            String reservationRateVal = "";
            if (!ZERO.equals(openOrderNum) && !ZERO.equals(reservationRateQuantity)) {
                double reservationRate = Double.parseDouble(reservationRateQuantity) / Double.parseDouble(openOrderNum) * 100.0;
                reservationRateVal = handleParam(df.format(reservationRate), 0);
            }
            scheduleChartsResponseDto.setReservationRate(reservationRateVal);
            String timelyArrivalRateVal = "";
            if (!ZERO.equals(allocatedQuantity) && !ZERO.equals(timelyArrivalQuantity)) {
                double timelyArrivalRate = Double.parseDouble(timelyArrivalQuantity) / Double.parseDouble(allocatedQuantity) * 100.0;
                timelyArrivalRateVal = handleParam(df.format(timelyArrivalRate), 0);
            }
            scheduleChartsResponseDto.setTimelyArrivalRate(timelyArrivalRateVal);
            String complianceRateVal = "";
            if (!ZERO.equals(complianceQuantity) && !ZERO.equals(allocatedQuantity)) {
                double complianceRate = Double.parseDouble(complianceQuantity) / Double.parseDouble(allocatedQuantity) * 100.0;
                complianceRateVal = handleParam(df.format(complianceRate), 0);
            }
            scheduleChartsResponseDto.setComplianceRate(complianceRateVal);
            String averageReservationTimeVal = "";
            if (!ZERO.equals(reservationTime) && !ZERO.equals(allocatedQuantity)) {
                double averageReservationTime = Double.parseDouble(reservationTime) / Double.parseDouble(allocatedQuantity);
                averageReservationTimeVal = handleParam(df.format(averageReservationTime), 1);
            }
            scheduleChartsResponseDto.setAverageReservationTime(averageReservationTimeVal);
        } catch (Exception e) {
            log.error("=====getScheduleChartsNumber方法发生错误=====");
        }
    }

    @Override
    public ScheduleChartsDataDto getChangeChannelOrSource(ScheduleChartsRequestDto scheduleChartsRequestDto) {
        ScheduleChartsDataDto chartsDto = new ScheduleChartsDataDto();
        getTime(scheduleChartsRequestDto);
        getChartsGraphical(scheduleChartsRequestDto, chartsDto);
        return chartsDto;
    }

    private void getScheduleChartsGraphical(ScheduleChartsResponseDto scheduleChartsResponseDto, ScheduleChartsRequestDto scheduleChartsRequestDto) {
        ScheduleChartsDataDto chartsDto = new ScheduleChartsDataDto();
        List<Map<String, Object>> reservationChannel = scheduleChartsMapper.getReservationChannel(scheduleChartsRequestDto);
        List<Map<String, Object>> patientSource = scheduleChartsMapper.getPatientSource(scheduleChartsRequestDto);
        chartsDto.setReservationChannel(reservationChannel);
        chartsDto.setPatientSource(patientSource);
        getChartsGraphical(scheduleChartsRequestDto, chartsDto);
        scheduleChartsResponseDto.setChartsData(chartsDto);
    }

    private void getScheduleChartsGraphicalForCharts(ScheduleChartsResponseDto response, ScheduleChartsRequestDto request) {
        ScheduleChartsDataDto chartsDto = new ScheduleChartsDataDto();
        List<Map<String, Object>> reservationChannel = examScheduleChartsMapper.getReservationChannel(request);
        List<Map<String, Object>> patientSource = examScheduleChartsMapper.getPatientSource(request);
        chartsDto.setReservationChannel(reservationChannel);
        chartsDto.setPatientSource(patientSource);
        request.setFlag("1");
        request.setType("1");
        List<Map<String, Object>> allocatedList = examScheduleChartsMapper.getAllocatedOrTimelyArrivalQuantityCharts(request);
        request.setType("4");
        List<Map<String, Object>> timelyArrivalList = examScheduleChartsMapper.getAllocatedOrTimelyArrivalQuantityCharts(request);
        List<Map<String, Object>> allocatAndTimeArrQuantity = allocatAndTimeArrQuantityList(allocatedList, timelyArrivalList, request.getFlag());
        List<Map<String, Object>> zzjAllocatedQuantity = examScheduleChartsMapper.getzzjAllocatedQuantity(request);
        List<Map<String, Object>> patientSourceRateList = examScheduleChartsMapper.getPatientSource(request);
        List<Map<String, Object>> patientSourceRate = new ArrayList<>();
        if (!CollectionUtils.isEmpty(patientSourceRateList)) {
            patientSourceRate = patientSourceRateHandle(patientSourceRateList);
        }
        request.setType("5");
        List<Map<String, Object>> allocatedTimelyArrivalList = examScheduleChartsMapper.getAllocatedOrTimelyArrivalQuantityCharts(request);
        request.setType("6");
        List<Map<String, Object>> checkWaitTimeDistribute = examScheduleChartsMapper.getAllocatedOrTimelyArrivalQuantityCharts(request);
        getCheckWaitTimeDistribute(allocatedTimelyArrivalList, checkWaitTimeDistribute);
        chartsDto.setCheckWaitTimeDistribute(checkWaitTimeDistribute);
        chartsDto.setZzjAllocatedQuantity(zzjAllocatedQuantity);
        chartsDto.setPatientSourceRate(patientSourceRate);
        chartsDto.setAllocatedAndInspectionQuantity(allocatAndTimeArrQuantity);
        response.setChartsData(chartsDto);
    }

    private void getCheckWaitTimeDistribute(List<Map<String, Object>> allocatedTimelyArrivalList, List<Map<String, Object>> checkWaitTimeDistribute) {
        DecimalFormat df = new DecimalFormat("0");
        if (checkWaitTimeDistribute != null && checkWaitTimeDistribute.size() > 0) {
            for (Map<String, Object> map : checkWaitTimeDistribute) {
                String name = map.get("name").toString();
                for (Map<String, Object> allocatedMap : allocatedTimelyArrivalList) {
                    String allocatedName = allocatedMap.get("name").toString();
                    if (name.equals(allocatedName)) {
                        double allocatedTimelyArrival = Double.parseDouble(map.get("time").toString()) / Double.parseDouble(allocatedMap.get("time").toString());
                        map.put("time", df.format(allocatedTimelyArrival));
                    }
                }
            }
        }
    }

    private void getChartsGraphical(ScheduleChartsRequestDto scheduleChartsRequestDto, ScheduleChartsDataDto chartsDto) {
        scheduleChartsRequestDto.setFlag("1");
        CompletableFuture<List<Map<String, Object>>> timelyArrivalFuture = CompletableFuture.supplyAsync(() -> scheduleChartsMapper.getTimelyArrivalQuantityCharts(scheduleChartsRequestDto));
        CompletableFuture<List<Map<String, Object>>> patientSourceRateFuture = CompletableFuture.supplyAsync(() -> scheduleChartsMapper.getPatientSource(scheduleChartsRequestDto));
        CompletableFuture<List<Map<String, Object>>> zzjAllocatedQuantityFuture = CompletableFuture.supplyAsync(() -> scheduleChartsMapper.getzzjAllocatedQuantity(scheduleChartsRequestDto));
        CompletableFuture<List<Map<String, Object>>> checkWaitTimeDistributeFuture = CompletableFuture.supplyAsync(() -> scheduleChartsMapper.getCheckWaitTimeDistribute(scheduleChartsRequestDto));
        CompletableFuture.allOf(timelyArrivalFuture, patientSourceRateFuture, zzjAllocatedQuantityFuture, checkWaitTimeDistributeFuture);
        try {
            List<Map<String, Object>> allocatedList = scheduleChartsMapper.getAllocatedQuantityCharts(scheduleChartsRequestDto);
            List<Map<String, Object>> timelyArrivalList = timelyArrivalFuture.get();
            List<Map<String, Object>> allocatAndTimeArrQuantity = allocatAndTimeArrQuantityList(allocatedList, timelyArrivalList, scheduleChartsRequestDto.getFlag());
            List<Map<String, Object>> patientSourceRateList = patientSourceRateFuture.get();
            List<Map<String, Object>> patientSourceRate = new ArrayList<>();
            if (patientSourceRateList != null && patientSourceRateList.size() > 0) {
                patientSourceRate = patientSourceRateHandle(patientSourceRateList);
            }
            List<Map<String, Object>> zzjAllocatedQuantity = zzjAllocatedQuantityFuture.get();
            List<Map<String, Object>> checkWaitTimeDistribute = checkWaitTimeDistributeFuture.get();
            HandleCheckWaitTimeDistribute(checkWaitTimeDistribute);
            chartsDto.setCheckWaitTimeDistribute(checkWaitTimeDistribute);
            chartsDto.setZzjAllocatedQuantity(zzjAllocatedQuantity);
            chartsDto.setPatientSourceRate(patientSourceRate);
            chartsDto.setAllocatedAndInspectionQuantity(allocatAndTimeArrQuantity);
        } catch (InterruptedException | ExecutionException e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public ScheduleChartsResponseDto getChartsTrendGraphAnalysis(ScheduleChartsRequestDto scheduleChartsRequestDto) {
        ScheduleChartsResponseDto scheduleChartsResponseDto = new ScheduleChartsResponseDto();
        ScheduleChartsTrendDto chartsTrendDto = new ScheduleChartsTrendDto();
        String examClassName = scheduleChartsRequestDto.getExamClassName();
        List<String> name = new ArrayList<>();
        if (!StringUtils.isEmpty(examClassName)) {
            if (examClassName.equalsIgnoreCase("全院")) {
                name = scheduleChartsMapper.getDictDept(scheduleChartsRequestDto);
            } else {
                name = scheduleChartsMapper.getExamQueue(scheduleChartsRequestDto);
            }
        }
        chartsTrendDto.setName(name);
        getTime(scheduleChartsRequestDto);
        getChartsTrend(scheduleChartsRequestDto, chartsTrendDto);
        scheduleChartsResponseDto.setChartsTrend(chartsTrendDto);
        return scheduleChartsResponseDto;
    }

    @Override
    public ScheduleChartsTrendDto getChangeDeptOrQueue(ScheduleChartsRequestDto scheduleChartsRequestDto) {
        ScheduleChartsTrendDto chartsTrendDto = new ScheduleChartsTrendDto();
        String examClassName = scheduleChartsRequestDto.getExamClassName();
        String deptName = scheduleChartsRequestDto.getDeptName();
        if (COMPLETE.equals(deptName)) {
            scheduleChartsRequestDto.setDeptName("");
            scheduleChartsRequestDto.setQueueName("");
        }
        if (!Whole_Hospital.equals(examClassName) && !COMPLETE.equals(deptName)) {
            scheduleChartsRequestDto.setQueueName(deptName);
            scheduleChartsRequestDto.setDeptName("");
        }
        getTime(scheduleChartsRequestDto);
        getChartsTrend(scheduleChartsRequestDto, chartsTrendDto);
        return chartsTrendDto;
    }

    private void getChartsTrend(ScheduleChartsRequestDto scheduleChartsRequestDto, ScheduleChartsTrendDto chartsTrendDto) {
        scheduleChartsRequestDto.setFlag("2");
        List<Map<String, Object>> orderNumList = scheduleChartsMapper.getOpenOrderNum(scheduleChartsRequestDto);
        List<Map<String, Object>> reQuantityList = scheduleChartsMapper.getReservationRateQuantity(scheduleChartsRequestDto);
        List<Map<String, Object>> reservationRateWeekList = list(orderNumList, reQuantityList, "openOrderNum", "reservationRateQuantity");

        List<Map<String, Object>> allocatedList = scheduleChartsMapper.getAllocatedQuantityCharts(scheduleChartsRequestDto);
        List<Map<String, Object>> timelyArrivalList = scheduleChartsMapper.getTimelyArrivalQuantityCharts(scheduleChartsRequestDto);
        List<Map<String, Object>> allocatedAndTimelyArrivalQuantityList = allocatAndTimeArrQuantityList(allocatedList, timelyArrivalList, scheduleChartsRequestDto.getFlag());
        List<Map<String, Object>> checkWaitTimeWeekDistribute = scheduleChartsMapper.getCheckWaitTimeWeekDistribute(scheduleChartsRequestDto);
        HandleCheckWaitTimeDistribute(checkWaitTimeWeekDistribute);
        List<Map<String, Object>> complianceQuantityList = scheduleChartsMapper.getComplianceQuantityCount(scheduleChartsRequestDto);
        List<Map<String, Object>> complianceRateWeekList = list(allocatedList, complianceQuantityList, "allocatedQuantity", "complianceQuantity");


        chartsTrendDto.setCheckWaitTimeWeekDistribute(checkWaitTimeWeekDistribute);
        chartsTrendDto.setReservationRateWeek(reservationRateWeekList);
        chartsTrendDto.setComplianceRateWeek(complianceRateWeekList);
        chartsTrendDto.setAllocatedAndInspectionQuantity(allocatedAndTimelyArrivalQuantityList);
    }

    public void examScheduleCharts(ExamScheduleCharts chasrts) {
        resultSaveMapper.deleteCharts(chasrts);
        resultSaveMapper.getExamScheduleCount(chasrts);
        resultSaveMapper.getCheckCount(chasrts);
        resultSaveMapper.getComplianceQuantityCount(chasrts);
        resultSaveMapper.getComplianceQuantityCount2(chasrts);
        resultSaveMapper.getTimelyCheckCount(chasrts);
        resultSaveMapper.getInspectionQuantity(chasrts);
        resultSaveMapper.getCheckWaitTime(chasrts);
        resultSaveMapper.getReservationTime(chasrts);
        resultSaveMapper.getCheckTotalCount(chasrts);
        resultSaveMapper.getCheckScheduleCount(chasrts);
    }

    private void HandleCheckWaitTimeDistribute(List<Map<String, Object>> list) {
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); ++i) {
                Map<String, Object> map = list.get(i);
                String time = map.get("time").toString();
                if (ZERO.equals(time)) {
                    list.remove(i);
                    --i;
                }
            }
            collectionSort(list);
        }
    }

    private List<Map<String, Object>> patientSourceRateHandle(List<Map<String, Object>> list) {
        DecimalFormat df = new DecimalFormat("0.##");
        List<Map<String, Object>> patientSourceRateList = new ArrayList<>();
        List<String> diff = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (Map<String, Object> stringObjectMap : list) {
                String patientSourceName = stringObjectMap.get("patientSourceName") + "";
                if (!diff.contains(patientSourceName)) {
                    diff.add(patientSourceName);
                }
            }
        }
        Map<String, Object> map = new HashMap<>();
        for (String s : diff) {
            List<Map<String, Object>> patientSourceList = new ArrayList<>();
            for (Map<String, Object> stringObjectMap : list) {
                Map<String, Object> patientSourceMap = new HashMap<>();
                String name = stringObjectMap.get("patientSourceName") + "";
                if (Objects.nonNull(s) && s.equalsIgnoreCase(name)) {
                    String patientSourceCount = stringObjectMap.get("patientSourceCount") + "";
                    String patientSource = stringObjectMap.get("patientSource") + "";
                    patientSourceMap.put("patientSource", patientSource);
                    patientSourceMap.put("patientSourceCount", patientSourceCount);
                    patientSourceList.add(patientSourceMap);
                }
            }
            double count = 0.0;
            for (Map<String, Object> stringObjectMap : patientSourceList) {
                count += Double.parseDouble(stringObjectMap.get("patientSourceCount").toString());
            }

            for (Map<String, Object> percentageMap : patientSourceList) {
                double percentage = Double.parseDouble(percentageMap.get("patientSourceCount").toString()) / count * 100.0;
                percentageMap.put("percentage", handleParam(df.format(percentage), 2));
            }
            map.put(s, patientSourceList);
        }
        patientSourceRateList.add(map);
        return patientSourceRateList;
    }

    private List<Map<String, Object>> allocatAndTimeArrQuantityList(List<Map<String, Object>> allocatedList, List<Map<String, Object>> timelyArrivalList, String flag) {
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            String val = WEEK;
            if ("1".equals(flag)) {
                val = "name";
            }
            List<String> diffWeek = getDiffrent(allocatedList, timelyArrivalList, val);
            if (!CollectionUtils.isEmpty(diffWeek)) {
                for (String s : diffWeek) {
                    Map<String, Object> map = new HashMap<>();
                    map.put(val, s);
                    map.put("allocatedQuantity", "0");
                    map.put("timelyArrivalQuantity", "0");
                    if (allocatedList != null && allocatedList.size() > 0) {
                        for (Map<String, Object> stringObjectMap : allocatedList) {
                            String val2 = stringObjectMap.get(val) + "";
                            if (s.equalsIgnoreCase(val2)) {
                                String allocatedQuantity = stringObjectMap.get("allocatedQuantity") + "";
                                map.put("allocatedQuantity", allocatedQuantity);
                            }
                        }
                    }
                    if (timelyArrivalList != null && timelyArrivalList.size() > 0) {
                        for (Map<String, Object> stringObjectMap : timelyArrivalList) {
                            String val3 = stringObjectMap.get(val) + "";
                            if (s.equalsIgnoreCase(val3)) {
                                String timelyArrivalQuantity = stringObjectMap.get("timelyArrivalQuantity") + "";
                                map.put("timelyArrivalQuantity", timelyArrivalQuantity);
                            }
                        }
                    }
                    list.add(map);
                }
            }
        } catch (Exception e) {
            log.error("=====allocatAndTimeArrQuantityList方法发生错误=====");
        }
        return list;
    }

    private List<String> getDiffrent(List<Map<String, Object>> list1, List<Map<String, Object>> list2, String val) {
        List<String> diff = new ArrayList<>();
        try {
            if (list1 != null && list1.size() > 0) {
                for (Map<String, Object> stringObjectMap : list1) {
                    String week = stringObjectMap.get(val) + "";
                    diff.add(week);
                }
            }
            if (list2 != null && list2.size() > 0) {
                for (Map<String, Object> stringObjectMap : list2) {
                    String week = stringObjectMap.get(val) + "";
                    if (!diff.contains(week)) {
                        diff.add(week);
                    }
                }
            }
        } catch (Exception e) {
            log.error("=====getDiffrent方法发生错误=====");
        }
        return diff;
    }

    private List<Map<String, Object>> list(List<Map<String, Object>> list1, List<Map<String, Object>> list2, String val1, String val2) {
        List<Map<String, Object>> list3 = new ArrayList<>();
        try {
            DecimalFormat df = new DecimalFormat("0.##");
            if (list1 != null && list1.size() > 0 && list2 != null && list2.size() > 0) {
                for (Map<String, Object> stringObjectMap : list1) {
                    String week1 = stringObjectMap.get(ScheduleChartsServicelmpl.WEEK) + "";
                    for (Map<String, Object> objectMap : list2) {
                        String week2 = objectMap.get(ScheduleChartsServicelmpl.WEEK) + "";
                        if (week1.equalsIgnoreCase(week2)) {
                            String num1 = stringObjectMap.get(val1) + "";
                            String num2 = objectMap.get(val2) + "";
                            double rate = Double.parseDouble(num2) / Double.parseDouble(num1) * 100.0;
                            String rateVal = df.format(rate);
                            Map<String, Object> map = new HashMap<>();
                            map.put(WEEK, week1);
                            map.put("percentage", rateVal + "%");
                            list3.add(map);
                        }
                    }
                }
            }
            collectionSort(list3);
        } catch (Exception e) {
            log.error("=====list方法发生错误=====");

        }
        return list3;
    }

    private void collectionSort(List<Map<String, Object>> list) {
        list.sort((o1, o2) -> {
            String name1 = (o1.get(WEEK) == null) ? "" : o1.get(WEEK).toString();
            String name2 = (o2.get(WEEK) == null) ? "" : o2.get(WEEK).toString();
            return name1.compareTo(name2);
        });
    }

    private String handleParam(String val, int flag) {
        if (!val.equals("0")) {
            if (flag == 1) {
                val += "h";
            } else {
                val += "%";
            }
        }
        return val;
    }

    private String isNotNull(String val) {
        if (StringUtils.isEmpty(val) || ZERO.equals(val)) {
            val = "";
        }
        return val;
    }
}
